package tracer;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

import tracer.RayTracerRunning;

/**
 * This is main class for receiving parameters from command line
 * It will also proceed function execution
 * 
 * @author Yuting Wu
 * @author Kan Lin
 * @author Bing Dong
 */
public class Tracer {

	public static void main(String[] args) throws IOException {
		//Start timer
		long startTime = 0;
		//End timer
		long endTime = 0;
		//Judge whether it should start timer
		boolean ifTimeer = false;
		//log variable
		Logger log = Logger.getLogger("Tracer");
		//log related information
		FileHandler fileHandler = new FileHandler("ftracer_log.log");
		fileHandler.setLevel(Level.INFO);
		fileHandler.setFormatter(new LogFormatHander());
		log.addHandler(fileHandler);

		if (args.length == 0) {		
			log.warning("No argument input!Start again!");
		} else {

			int imgWidth = 0;
			int imgHeight = 0;
			int picWidth = 0;
			int picHeight = 0;

			int reflectDepth = 5;
			int threadNum = 1;

			double zoom = 0.0;
			String fileRead = "";
			String fileWrite = "";
			
			boolean check = false;

			int times = 0;

			boolean ifShadowAndReflect = true;

			while (!check) {
				String[] newArgs;
				if (times == 0) {
					newArgs = args;
				} else {
					// System.out.println("Some Argument are wrong!");
					log.warning("Some Argument are wrong!");
					BufferedReader stdin = new BufferedReader(
							new InputStreamReader(System.in));
					log.info("Argument Input again");
					newArgs = stdin.readLine().split(" ");
				}
				times++;
				if (newArgs.length > 7) {
					/*
					 * System.out.println("The" + 0 + "argument: num " + +
					 * newArgs.length);
					 */
					if (newArgs[0] != null && newArgs[0].endsWith(".xml")
							&& newArgs[1] != null
							&& newArgs[1].endsWith(".ppm")) {
						fileRead = newArgs[0];
						fileWrite = newArgs[1];
						log.info("The " + 0 + " argument:" + newArgs[0]);
						log.info("The " + 1 + " argument:" + newArgs[1]);
						check = true;

					}
				} else {
					check = false;
				}
				int num = 0;
				boolean flagx = false;
				boolean flagy = false;
				boolean flagw = false;
				boolean flagh = false;

				if (check) {
					for (int i = 2; newArgs != null && i < newArgs.length; i++) {
						if (newArgs[i].equals("-r")) {
							i++;
							if (i < newArgs.length) {
								reflectDepth = Integer.parseInt(newArgs[i]);
							} else {
								check = false;
							}

						} else if (newArgs[i].equals("-q")) {

							ifShadowAndReflect = false;

						} else if (newArgs[i].equals("-z")) {
							i++;
							if (i < newArgs.length) {
								zoom = Double.parseDouble(newArgs[i]);
							} else {
								check = false;
							}

						} else if (newArgs[i].equals("-x")) {
							i++;
							if (i < newArgs.length) {
								imgWidth = Integer.parseInt(newArgs[i]);
								num++;
								flagx = true;
							} else {
								check = false;
							}

						} else if (newArgs[i].equals("-y")) {
							i++;
							if (i < newArgs.length) {
								imgHeight = Integer.parseInt(newArgs[i]);
								num++;
								flagy = true;
							} else {
								check = false;
							}

						} else if (newArgs[i].equals("-w")) {
							i++;
							if (i < newArgs.length) {
								picWidth = Integer.parseInt(newArgs[i]);
								num++;
								flagw = true;
							} else {
								check = false;
							}

						} else if (newArgs[i].equals("-h")) {
							i++;
							if (i < newArgs.length) {
								picHeight = Integer.parseInt(newArgs[i]);
								num++;
								flagh = true;
							} else {
								check = false;
							}

						} else if (newArgs[i].equals("-p")) {
							i++;
							if (i < newArgs.length) {
								threadNum = Integer.parseInt(newArgs[i]);

							} else {
								check = false;
							}

						} else if (newArgs[i].equals("-t")) {
							ifTimeer = true;
						}
					}
				}
				if (zoom == 0.0) {
					check = false;
				}
				if (check) {
					if (num < 3) {
						check = false;
					} else if (num == 3) {
						if (!flagx) {
							imgWidth = picWidth * imgHeight / picHeight;
						}
						if (!flagy) {
							imgHeight = picHeight * imgWidth / picWidth;

						}
						if (!flagw) {
							picWidth = imgWidth * picHeight / imgHeight;
						}
						if (!flagh) {
							picHeight = imgHeight * picWidth / imgWidth;
						}
						check = true;
					} else if (num == 4) {
						if (imgWidth != picWidth * imgHeight / picHeight) {
							check = false;
						}
					}
				}
			}
			//Start timer
			startTime = System.currentTimeMillis();			
			RayTracerRunning rtr = new RayTracerRunning();			
			rtr.runTracer(imgWidth, imgHeight, picWidth,
					picHeight, threadNum, zoom, fileRead, fileWrite,
					ifShadowAndReflect, reflectDepth);

		}
		//End timer
		endTime = System.currentTimeMillis();
		long lastTime = endTime - startTime;
		log.info("Program End");
		if (ifTimeer == true) {
			log.info("Program takes " + lastTime + " milliseconds");
			long times = 0;
			try {
				File file = new File("timer");
				if (file.exists()) {
					BufferedReader in = new BufferedReader(
							new InputStreamReader(new FileInputStream("timer")));
					String temp = in.readLine();

					if ("".endsWith(temp)) {
						times = lastTime;
					} else {
						times = lastTime + Integer.parseInt(temp);
					}
					FileOutputStream fos = new FileOutputStream("timer");
					PrintStream pStream = new PrintStream(fos);
					pStream.println(times);
					fos.close();
				}
			} catch (Exception e) {
				e.getStackTrace();
			}
		}
	}

}
